<?php


namespace Muyuxuan\tool;


class Mtool
{
    /**
     * 求经纬度距离
     * @param array|float[] $location1 数组，必须元素（long经度，lat纬度）
     * @param array|float[] $location2 数组，必须元素（long经度，lat纬度）
     * @param string $unit 距离单位 m=米, km=千米,mi=英里,ft=英尺
     * @return float|int
     */
    public static function getDistance(array $location1=['long'=>0,'lat'=>0],array $location2=['long'=>0,'lat'=>0],string $unit='m'){
        $EARTH_RADIUS = 6378.137;
        $radLat1 = self::rad($location1['lat']);
        $radLat2 = self::rad($location2['lat']);
        $a = $radLat1 - $radLat2;
        $b = self::rad($location1['long']) - self::rad($location2['long']);
        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $s = $s * $EARTH_RADIUS;
        $s = round($s * 10000) / 10000;
        $s = $s*1000;
        if($unit=="km"){
            $s = $s/1000;
        }elseif ($unit=='mi'){
            $s = $s*0.000621371;
        }elseif ($unit=='ft'){
            $s = $s*3.281;
        }
        return $s;
    }
    protected static function rad($d){
        return $d * M_PI / 180.0;
    }

    /**
     * 获取订单编号
     * @param int $num
     * @param string $userId
     * @param string $prefix
     * @return string
     */
    public static function getOrderNum(int $num=15,string $userId='',string $prefix=''){
        $str = $prefix.date('YmdHis').strrev(uniqid($userId));
        while (true){
            if(strlen($str)<$num){
                $str .= strrev(uniqid($userId));
            }else{
                break;
            }
        }
        return mb_substr($str,0,$num);
    }

    /**
     * 获取定长的商户号
     * @param int $num 位数
     * @param string $userId 用户id
     * @param string $prefix 前缀
     * @return string
     */
    public static function getMerchant(int $num=15,string $userId='',string $prefix=''){
        if($num>32){
            return '';
        }
        $str = $prefix.date('YmdHis').strrev(uniqid($userId));
        $str = md5($str);
        return mb_substr($str,0,$num);
    }

    /**
     * 加密
     * @param string $passWord 需加密字符串
     * @param string $salt 密码盐
     * @param string $type 支持md5和 sha256
     * @return string
     */
    public static function passWordEncode(string $passWord,string $salt='',string $type='md5'){
        if($type=='md5'){
            $passWord = md5(md5($passWord).$salt);
            return $passWord;
        }else{
            $passWord = hash($type,hash($type,$passWord).$salt);
            return $passWord;
        }
    }

    /**验证密码是否正确
     * @param string $passWord 密码
     * @param string $verify 加密字符串
     * @param string $salt 密码盐
     * @param string $type 支持md5和 sha256
     * @return bool
     */
    public static function PassWordVerify(string $passWord,string $verify,string $salt='',string $type='md5'){
        $pas = self::passWordEncode($passWord,$salt,$type);
        if(strval($pas)===strval($verify)){
            return true;
        }else{
            return false;
        }
    }

    /**获取固定长度随机字符串
     * @param int $num 字符串长度
     * @param string $character 可用的字符集
     * @return string
     */
    public static function getRandomStr(int $num=4,string $character=""){
        if(empty($character)){
            $character = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        }
        $count = mb_strlen($character);
        $str = '';
        for ($a=0;$a<$num;$a++){
            $str .= $character[mt_rand(0,$count-1)];
        }
        return $str;
    }

    /**获取子订单号码
     * @param string $hostStr
     * @param int $num
     * @param array $nodHas
     * @return array
     */
    public static function getChildOrderNum(string $hostStr,int $num = 1,array $nodHas=[]){
        $hasnum = 0;
        $strArray = [];
        $start = 0;
        while ($hasnum<$num){
            $newstr = $hostStr.'_'.$start;
            if(!in_array($newstr,$nodHas)){
                $strArray[] = $newstr;
                $hasnum++;
            }
            $start++;
        }
        return $strArray;
    }

    /**
     * 隐藏字符串
     * @Param string $str
     * @Param int $start 起始位置 从0开始计数  负数倒转替换
     * @Param int|string $length 当 $length=string 替换 $key
     * @Param int|string $key 填充的隐藏的字符 默认 *
     * @Param string $charset 可废弃 删除 ($key && $charset = $key) 和 ($charset='utf8') 语句;
     */
    public static function hidenStr($str,$start,$length=0,$key='',$charset='utf8'){
        if(strlen($length) && gettype($length) != "integer"){
            $key && $charset = $key;
            $key = $length;
            $length = 0;
        }
        $Par = $length?[$start,$length]:[$start]; //array_filter([$start,$length]);
        // use $charset;
        //$e or $e = mb_strlen($str);
        //$Par     = [$start,$length,$charset];
        $rep_str = mb_substr($str,...$Par);
        strlen($key) or $key = '*';
        strlen($key) == 1 && $key = str_pad('',mb_strlen($rep_str),$key);
        $start  = strlen(mb_substr($str,0,$start));
        $count  = strlen($rep_str);
        $result = substr_replace($str,$key,$start,$count);
        return $result;
    }

    /**
     * 字符串中包含表情
     * @param string $str
     * @return bool
     */
    public static function haveEmojiChar(string $str){
        $mbLen = mb_strlen($str);
        $strArr = [];
        for ($i = 0; $i < $mbLen; $i++) {
            $strArr[] = mb_substr($str, $i, 1, 'utf-8');
            if (strlen($strArr[$i]) >= 4) {
                return true;
            }
        }
        return false;
    }

    /**
     * 删除字符串表情字符串
     * @param $str
     * @return string
     */
    public static  function removeEmojiChar(string $str){
        $mbLen = mb_strlen($str);
        $strArr = [];
        for ($i = 0; $i < $mbLen; $i++) {
            $mbSubstr = mb_substr($str, $i, 1, 'utf-8');
            if (strlen($mbSubstr) >= 4) {
                continue;
            }
            $strArr[] = $mbSubstr;
        }
        return implode('', $strArr);
    }

    /**
     * 表情字符串加密保存
     * @param string $str
     * @return string
     */
    public static function emojiCharEncode(string $str){
        return base64_encode($str);
    }

    /**
     * 表情字符串解密
     * @param string $str
     * @return string
     */
    public static function emojiCharDecode(string $str){
        $a = base64_decode($str);
        if(empty($a)){
            return $str;
        }
        return $a;
    }

    /**
     * 提取二维数组到一维数组
     * @param array $array
     * @param string $keyField
     * @param string $titleField
     * @return array|false
     */
    public static function extractCombine(array $array,string $keyField='id',string $titleField='title'){
        return array_combine(array_column($array,$keyField),array_column($array,$titleField));
    }

    /**
     * 阿拉伯数组转化成中文数字
     * @param $num
     * @return false|string
     */
    public static function numberToChinese($num) {
        $chineseNumber = array(0 => '零', 1 => '一', 2 => '二', 3 => '三', 4 => '四', 5 => '五', 6 => '六', 7 => '七', 8 => '八', 9 => '九');

        // 判断输入参数类型是否正确
        if (!is_numeric($num)) {
            return false;
        }

        // 处理小数部分
        $res = explode('.', strval($num));
        $integerPart = $res[0];
        $decimalPart = empty($res[1])?"":$res[0];


        // 处理整数部分
        $result = '';
        for ($i = 0; isset($integerPart[$i]); ++$i) {
            $digit = intval($integerPart[$i]);
            $unit = "";
            // 根据位置添加单位（千、百万等）
            switch (strlen($integerPart) - $i - 1) {
                case 0:
                    break;
                case 1:
                    $unit = '十';
                    break;
                case 2:
                    $unit = '百';
                    break;
                case 3:
                    $unit = '千';
                    break;
                case 4:
                    $unit = '万';
                    break;
                case 5:
                    $unit = '亿';
                    break;
                case 6:
                    $unit = '兆';
                    break;
                case 7:
                    $unit = '京';
                    break;
                case 8:
                    $unit = '垓';
                    break;
                case 9:
                    $unit = '秭';
                    break;
                case 10:
                    $unit = '穰';
                    break;
                case 11:
                    $unit = '沟';
                    break;
                case 12:
                    $unit = '涧';
                    break;
                default:
                    $unit = '';
                    break;
            }
            // 组合结果
            $result .= $chineseNumber[$digit] . $unit;
        }
        if(!empty($decimalPart)){
            $result .= "点";
            for($i = 0;$i<strlen($decimalPart);$i++){
                if(!empty($chineseNumber[$decimalPart[$i]])){
                    $result .= $chineseNumber[$decimalPart[$i]];
                }
            }
        }
        // 返回最终结果
        return $result;
    }
}